/*
Illuminator (LED drawing tool for iPhone)
Copyright (C) 2008
Nik S Denin
Ivan A Vlasov
Dmitriy A Jackovlev

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#import "DrawField.h"
#import "MainView.h" // this is for delegate methods

@implementation DrawField

- (id)initWithFrame:(CGRect)frame
{
	if ((self = [super initWithFrame:frame]) != nil)
	{
		m_fieldState = DFEnabled;
		m_fillingState = DFFilling;
		m_undoCounter = 0;
		
		m_lamp = [UIImage applicationImageNamed:@"lamp.png"];
		[self constructGrid];

		m_topToolbar = [[ILTopToolbar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0f, 58.0) withImage:[UIImage applicationImageNamed:@"toolbar_top.png"]];
		[m_topToolbar setDelegate:self];

		m_bottomToolbar = [[ILBottomToolbar alloc] initWithFrame:CGRectMake(0.0, 422.0, 320.0f, 58.0) withImage:[UIImage applicationImageNamed:@"toolbar_bottom.png"]];
		[m_bottomToolbar setDelegate:self];

		m_undoArray = [[NSMutableArray alloc] initWithCapacity:MAX_UNDO];

		int i;
		for (i = 0; i < MAX_UNDO; i++)
		{
			NSMutableDictionary *undoDict = [[NSMutableDictionary alloc] init];
			[undoDict setObject:[[NSMutableArray alloc] init] forKey:@"added"];
			[undoDict setObject:[[NSMutableArray alloc] init] forKey:@"removed"];
			[m_undoArray addObject:undoDict];
		}
	}
	return self;
}

- (void)showToolbars
{
	[UIApp _dumpScreenContents:nil];
	[UIView beginAnimations:nil];
	[UIView setAnimationDuration:ANIM_DURATION];
	[m_topToolbar show];
	[m_bottomToolbar show];
	[UIView endAnimations];
	m_fieldState = DFDisabled;
}

- (void)hideToolbars
{
	[m_topToolbar hide];
	[m_bottomToolbar hide];
	m_fieldState = DFEnabled;
}

- (void)constructGrid
{
	float i, j;
	
	for (i = 0; i < 320.0; i += LAMPDIM)
	{
		for (j = 0; j < 480.0; j += LAMPDIM)
		{
			m_gridPoints[(int)(i / LAMPDIM)][(int)(j / LAMPDIM)] = CGPointMake(i, j);
		}
	}
}

- (void)drawRect:(CGRect)rect
{
	CGContextDrawImage(UICurrentContext(), CGRectMake(0.0, 0.0, 320.0, 480.0f), [[UIImage applicationImageNamed:@"field.png"] imageRef]);
}

- (void)mouseDragged:(GSEvent *)event
{
	if (m_fieldState == DFEnabled)
	{
		CGPoint point = GSEventGetLocationInWindow(event);

		CGRect lampRect = CGRectMake(
			m_gridPoints[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)].x - (LAMPLIGHT - LAMPDIM)/2,
			m_gridPoints[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)].y - (LAMPLIGHT - LAMPDIM)/2,
			LAMPLIGHT,
			LAMPLIGHT
		);

		[self workingWithRect:lampRect withPoint:point];
	}
}

- (void)workingWithRect:(CGRect)lampRect withPoint:(CGPoint)point
{
	if (m_fillingState == DFErasing && [self containsView:m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)]])
	{
		[m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)] removeFromSuperview];
		[[[m_undoArray objectAtIndex:m_undoCounter] objectForKey:@"removed"] addObject:m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)]];
	}
	else if (m_fillingState == DFFilling &&![self containsView:m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)]])
	{
		m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)] = [[[UIImageView alloc] initWithFrame:lampRect] retain];
		[m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)] setImage:m_lamp];
		[self addSubview:m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)]];
		[[[m_undoArray objectAtIndex:m_undoCounter] objectForKey:@"added"] addObject:m_lampViews[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)]];
	}
}

- (void)mouseUp:(GSEvent *)event
{
	if (m_fieldState == DFEnabled)
		if (++m_undoCounter >= MAX_UNDO)
			m_undoCounter = MAX_UNDO-1;
	
	TRACE(@"Undo counter: %d", m_undoCounter);
}

- (void)mouseDown:(GSEvent *)event
{
	CGPoint point = GSEventGetLocationInWindow(event);

	if (CGRectContainsPoint(CGRectMake(0.0, 460.0, 20.0, 20.0), point))
	{
		TRACE(@"Showing toolbars...");
		[self showToolbars];
		return ;
	}

	if (m_fieldState == DFDisabled && CGRectContainsPoint(CGRectMake(0.0, [m_topToolbar frame].size.height, 320.0, 480.0 - ([m_bottomToolbar frame].size.height + [m_topToolbar frame].size.height)), point))
	{
		TRACE(@"Hiding toolbars...");
		[self hideToolbars];
		return ;
	}

	if (m_fieldState == DFEnabled)
	{
		CGRect lampRect = CGRectMake(
			m_gridPoints[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)].x - (LAMPLIGHT - LAMPDIM)/2,
			m_gridPoints[(int)(point.x / LAMPDIM)][(int)(point.y / LAMPDIM)].y - (LAMPLIGHT - LAMPDIM)/2,
			LAMPLIGHT,
			LAMPLIGHT
		);

		[self workingWithRect:lampRect withPoint:point];
	}
}

/* set small field size */
- (void)setSmallField
{

}

/* set medium field size */
- (void)setMediumField
{

}

/* set large field size */
- (void)setLargeField
{

}

/* invert image (invert all lamps on the field) */
- (void)invertImage
{

}

/* turn filling mode on and off
filling states are stored in FillState enumeration
(take a look into ILTopToolbar.h file)
*/
- (void)setFill:(short)state
{
	m_fillingState = state;
}

- (void)newImage
{
	float i, j;
	
	for (i = 0; i < 320.0; i += LAMPDIM)
	{
		for (j = 0; j < 480.0; j += LAMPDIM)
		{
			if ([self containsView:m_lampViews[(int)(i / LAMPDIM)][(int)(j / LAMPDIM)]])
			{
				[m_lampViews[(int)(i / LAMPDIM)][(int)(j / LAMPDIM)] removeFromSuperview];
				[m_lampViews[(int)(i / LAMPDIM)][(int)(j / LAMPDIM)] release];
			}
			m_thisSession[(int)(i / LAMPDIM)][(int)(j / LAMPDIM)] = NO;
		}
	}
}

- (void)saveImage
{

}

- (void)showList
{

}

- (void)mailImage
{
	[self hideToolbars];
	TRACE(@"mailImage called");
	[self slideUp];
}

- (void)bomb
{

}

- (void)setDelegate:(id)delegate
{
	m_delegate = delegate;
}

- (void)undo
{
	if (m_undoCounter > 0)
	{
		if ([m_undoArray objectAtIndex:m_undoCounter-1] != nil)
		{
			// remove added objects
			NSMutableArray *addedObjects = [[m_undoArray objectAtIndex:m_undoCounter-1] objectForKey:@"added"];
			int numOfAddedObjects = [addedObjects count];
			if (numOfAddedObjects > 0)
			{
				int i;
				for (i = 0; i < numOfAddedObjects; i++)
				{
					[[addedObjects objectAtIndex:i] removeFromSuperview];
				}
			}

			// add removed objects
			NSMutableArray *removedObjects = [[m_undoArray objectAtIndex:m_undoCounter-1] objectForKey:@"removed"];
			int numOfRemovedObjects = [removedObjects count];
			if (numOfRemovedObjects > 0)
			{
				int j;
				for (j = 0; j < numOfRemovedObjects; j++)
				{
					[self addSubview:[removedObjects objectAtIndex:j]];
					[self sendSubviewToBack:[removedObjects objectAtIndex:j]];
				}
			}
			if (m_undoCounter > 0)
				m_undoCounter--;
		}
	}
}

- (void)redo
{
	if ([m_undoArray objectAtIndex:m_undoCounter] != nil)
	{
		// remove added objects
		NSMutableArray *addedObjects = [[m_undoArray objectAtIndex:m_undoCounter] objectForKey:@"added"];
		int numOfAddedObjects = [addedObjects count];
		if (numOfAddedObjects > 0)
		{
			int i;
			for (i = 0; i < numOfAddedObjects; i++)
			{
				[self addSubview:[addedObjects objectAtIndex:i]];
				[self sendSubviewToBack:[addedObjects objectAtIndex:i]];
			}
		}

		// add removed objects
		NSMutableArray *removedObjects = [[m_undoArray objectAtIndex:m_undoCounter] objectForKey:@"removed"];
		int numOfRemovedObjects = [removedObjects count];
		if (numOfRemovedObjects > 0)
		{
			int j;
			for (j = 0; j < numOfRemovedObjects; j++)
			{
				[[removedObjects objectAtIndex:j] removeFromSuperview];
			}
		}
		if (m_undoCounter < MAX_UNDO && (numOfAddedObjects > 0 || numOfRemovedObjects > 0))
			m_undoCounter++;
	}
}

- (short)getFillingState
{
	return m_fillingState;
}

- (void)dealloc
{
	[super dealloc];
}

/*
Usage:
[self slideUp];
*/

- (void)slideUp
{
	TRACE(@"slideUp called");
	NSMutableArray *buttons = [[NSMutableArray alloc] init];
	[buttons addObject:@"Post to Twitter"];
	[buttons addObject:@"Mail picture"];
	[buttons addObject:@"Cancel"];
	UIAlertSheet *alertSheet = [[[UIAlertSheet alloc]
			initWithTitle:@""
			buttons:buttons
			defaultButtonIndex:2
			delegate:self
			context:@"sendSheet"
			] autorelease];
	[alertSheet setAlertSheetStyle:2];
	[alertSheet presentSheetInView:self];
}

- (void)alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button
{
	NSString *context = [sheet context];
	if ([context isEqualToString:@"sendSheet"])
	{
		switch (button)
		{
			case 1:
			{
				[m_delegate showTwitterView];
				TRACE(@"Twitter button pressed...");
				break;
			}
			case 2:
			{
				[m_delegate mail:[NSData dataWithContentsOfFile:@"/tmp/foo_0.png"]];
				TRACE(@"Mail button pressed...");
				break;
			}
			case 3:
				TRACE(@"Cancel button pressed...");
				break;
			default:
				TRACE(@"Unknown button pressed...");
				break;
		}
	}
	[sheet dismiss];
}

-(void)didDismissAlertSheet:(id)alertSheet
{
	TRACE(@"alertSheet %@ dismissed...", alertSheet);
	//Hide TopBar and BottomBar, take screenshot and...
}

@end // DrawField
